package com.wlps.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wlps.contant.Contant;
import com.wlps.entity.*;
import com.wlps.mapper.CommodityMapper;
import com.wlps.mapper.CommodityWarehouseMapper;
import com.wlps.mapper.PurchaseReceiptMapper;
import com.wlps.mapper.SupplierMapper;
import com.wlps.result.ResultPageVo;
import com.wlps.result.ResultUtils;
import com.wlps.result.ResultVo;
import com.wlps.service.IPurchaseReceiptService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wlps.vo.sendcenter.inoutform.PurchaseReceiptAddVo;
import com.wlps.vo.warehousecenter.warehousing.PurchaseReceiptMapping;
import com.wlps.vo.warehousecenter.warehousing.PurchaseReceiptUpdateVo;
import com.wlps.vo.warehousecenter.warehousing.PurchaseReceiptVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 购货入库单表(purchase_receipt) 服务实现类
 * </p>
 *
 * @author ZWYZY
 * @since 2020-07-31
 */
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class PurchaseReceiptServiceImpl extends ServiceImpl<PurchaseReceiptMapper, PurchaseReceipt> implements IPurchaseReceiptService, InitializingBean {


    @Autowired
    PurchaseReceiptMapping purchaseReceiptMapping;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    CommodityMapper commodityMapper;

    @Autowired
    SupplierMapper supplierMapper;

    @Autowired
    CommodityWarehouseMapper commodityWarehouseMapper;

    @Override
    public void afterPropertiesSet() throws Exception {
        initPurchaseReceipt();


    }

    /**
     * 初始化缓存
     */
    void initPurchaseReceipt() {
        List<PurchaseReceipt> purchaseReceiptList;
        if (redisTemplate.hasKey(Contant.PURCHASERECEIPTS_KEY)) {
            purchaseReceiptList = (List<PurchaseReceipt>) redisTemplate.opsForValue().get(Contant.PURCHASERECEIPTS_KEY);
        } else {
            purchaseReceiptList = baseMapper.selectList(null);
            redisTemplate.opsForValue().set(Contant.PURCHASERECEIPTS_KEY, purchaseReceiptList,5, TimeUnit.MINUTES);
            log.info("初始化所有入库单-------存入缓存数据");
        }
        if (!redisTemplate.hasKey(Contant.PURCHASERECEIPTLIST_KEY)) {
            redisTemplate.opsForList().rightPushAll(Contant.PURCHASERECEIPTLIST_KEY, purchaseReceiptList);
            redisTemplate.expire(Contant.PURCHASERECEIPTLIST_KEY,5,TimeUnit.MINUTES);
            log.info("初始化入库单列表--------存入缓存数据");
        }
    }


    @Override
    public ResultPageVo<List<PurchaseReceiptVo>> getPurchaseReceiptVo(int pageNum, int pageSize, Long id) {
        initPurchaseReceipt();
        //总条数
        long count;
        List<PurchaseReceipt> purchaseReceiptList;

        if (id == null) {
            //不是条件查询，redis
            count = (Long) redisTemplate.opsForList().size(Contant.PURCHASERECEIPTLIST_KEY);
            //当前页从第几条开始查
            long fromNum = pageSize * (pageNum - 1);
            if (fromNum >= count) {
                purchaseReceiptList = (List<PurchaseReceipt>) redisTemplate.opsForList().range(Contant.PURCHASERECEIPTLIST_KEY, 0, count);
            } else {
                //当前页最后第几条
                long toNum = fromNum + pageSize >= count ? count : fromNum + pageSize;

                purchaseReceiptList = (List<PurchaseReceipt>) redisTemplate.opsForList().range(Contant.PURCHASERECEIPTLIST_KEY, fromNum, toNum-1);
            }

//            RedisConfig.returnJedis(jedis);

        } else {//条件查询，mysql
            Page<PurchaseReceipt> purchaseReceiptPage = new Page<>(pageNum, pageSize);
            LambdaQueryWrapper<PurchaseReceipt> queryWrapper = new QueryWrapper<PurchaseReceipt>().lambda().eq(PurchaseReceipt::getId, id);
            IPage<PurchaseReceipt> page = this.baseMapper.selectPage(purchaseReceiptPage, queryWrapper);
            purchaseReceiptList = page.getRecords();
            count = page.getSize();
        }
        //entity  to vo  映射
        List<PurchaseReceiptVo> purchaseReceiptVoList = purchaseReceiptMapping.entitysToVos(purchaseReceiptList);
        //分页返回值封装
        ResultPageVo resultPageVo = new ResultPageVo("响应成功", 200, (long) pageSize, (long) pageNum, count, purchaseReceiptVoList);

        return resultPageVo;

    }

    @Override
    public ResultVo editWarehouseingVo(long id, PurchaseReceiptUpdateVo purchaseReceiptUpdateVo) {
        PurchaseReceipt searchPurchaseReceipt = baseMapper.selectById(id);
        if (searchPurchaseReceipt == null) {
            return ResultUtils.error("入库单号查询不到，请输入正确的入库单号，亲", 10000);
        }
        if (searchPurchaseReceipt.getTaskStatus() == 1) {
            return ResultUtils.error("已经确认入库,无需重复入库，亲", 10001);
        }
        //1默认为中心库房
        CommodityWarehouse commodityWarehouse = baseMapper.selectCommodityWareHouseByCommodityName(searchPurchaseReceipt.getProductName(), 1);
        if (commodityWarehouse == null) {
            return ResultUtils.error("sorry,库房查询不到商品(" + searchPurchaseReceipt.getProductName() + "),亲", 10002);
        }
        if (purchaseReceiptUpdateVo.getActualVolume() > searchPurchaseReceipt.getPurchaseVolume()) {
            return ResultUtils.error("sorry,实际入库数量不能超过商品应入库数量,亲", 10003);
        }
        //计算库存量
        long number = commodityWarehouse.getCurrentNumber() + purchaseReceiptUpdateVo.getActualVolume();
        if (number > commodityWarehouse.getMaximumCommodity()) {
            return ResultUtils.error("当前商品库存量超出商品最大储量，亲，请重新输入实际入库数量", 10004);
        }

//        计算缺货量
        long defaultNumber = commodityWarehouse.getOutOfStockNumber();
        if (defaultNumber > 0) {
            if (defaultNumber - purchaseReceiptUpdateVo.getActualVolume() < 0) {
                defaultNumber = 0;
            } else {
                defaultNumber = defaultNumber - purchaseReceiptUpdateVo.getActualVolume();
            }
        }

        baseMapper.updateCommodityWarehouseCurrentNumber(searchPurchaseReceipt.getProductName(), 1, number, defaultNumber);
        PurchaseReceipt purchaseReceipt = new PurchaseReceipt();
        purchaseReceipt.setId(id);
        purchaseReceipt.setTaskStatus(1);
        BeanUtils.copyProperties(purchaseReceiptUpdateVo, purchaseReceipt);
        baseMapper.updateById(purchaseReceipt);
        purchaseReceiptUpdateCache();
        return ResultUtils.success("确认入库成功，亲");
    }

    @Override
    public ResultVo<PurchaseReceipt> addPurchaseReceiptAddVo(PurchaseReceiptAddVo purchaseReceiptAddVo) {
        Supplier supplier = supplierMapper.selectSupplierByName(purchaseReceiptAddVo.getSupplierName());
        if (supplier == null) {
//            throw new ApiException()
            return ResultUtils.error("系统未录入该供应商，请先录入供应商信息，亲", 10005);
        }
        Commodity commodity = commodityMapper.selectCommodityByName(purchaseReceiptAddVo.getProductName());
        if (commodity == null) {
            return ResultUtils.error("系统未录入该商品，请先录入商品信息，亲", 10006);
        }
        //1默认为中心库房
        CommodityWarehouse commodityWarehouse = baseMapper.selectCommodityWareHouseByCommodityName(purchaseReceiptAddVo.getProductName(), 1);
        if (commodityWarehouse == null) {
            commodityWarehouse = new CommodityWarehouse();
            commodityWarehouse.setWarehouseId(1L);
            commodityWarehouse.setCommodityId(commodity.getId());
            commodityWarehouse.setProductName(purchaseReceiptAddVo.getProductName());
            commodityWarehouse.setMaximumCommodity(100L);
            commodityWarehouse.setCurrentNumber(0L);
            commodityWarehouse.setOutOfStockNumber(0L);
            commodityWarehouseMapper.insert(commodityWarehouse);
//            return ResultUtils.error("中心库房未录入该商品，请先录入商品，亲", 10007);

        }
        long number = commodityWarehouse.getMaximumCommodity() - commodityWarehouse.getCurrentNumber() - purchaseReceiptAddVo.getPurchaseVolume();
//        if (number < 0) {
//            return ResultUtils.error("当前应入库数量:" + purchaseReceiptAddVo.getPurchaseVolume() + "\n大于\n当前商品最大储量:" + commodityWarehouse.getMaximumCommodity() + "\n-\n当前商品库存量：" + commodityWarehouse.getCurrentNumber() + "\n的区间,\n请重新输入应入库数量，亲", 10008);
//        }
        PurchaseReceipt purchaseReceipt = new PurchaseReceipt();
        BeanUtils.copyProperties(purchaseReceiptAddVo, purchaseReceipt);
        baseMapper.insert(purchaseReceipt);
        purchaseReceiptUpdateCache();
        return ResultUtils.success("生成入库单成功，亲", purchaseReceipt);
    }


    /**
     * 更新缓存
     */
    @Async
    public void purchaseReceiptUpdateCache() {
        List<PurchaseReceipt> purchaseReceiptList = baseMapper.selectList(null);
        redisTemplate.opsForValue().set(Contant.PURCHASERECEIPTS_KEY, purchaseReceiptList,5,TimeUnit.MINUTES);
        redisTemplate.delete(Contant.PURCHASERECEIPTLIST_KEY);
        redisTemplate.opsForList().rightPushAll(Contant.PURCHASERECEIPTLIST_KEY, purchaseReceiptList);
        redisTemplate.expire(Contant.PURCHASERECEIPTLIST_KEY,5,TimeUnit.MINUTES);
        redisTemplate.delete(Contant.INOUTVOS_KEY);
        log.info("所有入库单-------更新缓存数据");
    }


}
